/* asdbg.c */

/*
 *  Copyright (C) 2003-2025  Alan R. Baldwin
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Alan R. Baldwin
 * 721 Berkeley St.
 * Kent, Ohio  44240
 *
 *
 * Code extracted from asnoice.c
 * written by:
 *	John L. Hartman	(JLH)
 *	3-Nov-1997
 */

#include <ctype.h>
#include "dbuf_string.h"
#include "asxxxx.h"

/*)Module	asdbg.c
 *
 *	The module asdbg.c contains the functions that
 *
 *	1) generate debug symbols for assembler code
 *	   similiar to those generated by the SDCC compiler
 *
 *	2) generate debug symbols for the NoICE
 *	   remote debugger
 *
 *	asdbg.c contains the following functions:
 *		void	DefineSDCC_Line()
 *		void	DefineNoICE_Line()
 *		char *	BaseFileName()
 *
 *	asdbg.c contains the static variables:
 *		int	prevFile
 *		char	baseName[FILSPC]
 *
 *	    used by the BaseFileName function.
 *
 * NOTE:
 *	These functions know nothing about 'include' files
 *	and do not track their inclusion.
 */

/*)Function	void	DefineSDCC_Line(void)
 *
 *	The function DefineSDCC_Line() is called to create
 *	a symbol of the form A$FILE$nnn where FILE is the
 *	Base File Name, the file name without a path or
 *	an extension, and nnn is the line number.
 *
 *	local variables:
 *              struct dbuf_s   dbuf    a temporary to build the symbol
 *	        struct sym *	pSym	pointer to the created symbol structure
 *
 *	global variables:
 *              asmf *  asmc            pointer to current assembler file structure
 *		int	srcline		array of source file line numbers
 *		a_uint	laddr		current assembler address
 *		area	dot.s_area	pointer to the current area
 *
 *	functions called:
 *		char *	BaseFileName()	asdbg.c
 *		sym *	lookup()	assym.c
 *		int	sprintf()	c_library
 *
 *	side effects:
 *		A new symbol of the form A$FILE$nnn is created.
 */

#if SDCDB
void
DefineSDCC_Line(void)
{
        struct dbuf_s dbuf;
        struct sym *pSym;

	/*
	 * Symbol is A$FILE$nnn
	 */
        dbuf_init (&dbuf, NCPS);
        dbuf_printf (&dbuf, "A$%s$%u", BaseFileName (asmc, 1), srcline);

        pSym = lookup (dbuf_c_str (&dbuf));
        dbuf_destroy (&dbuf);

        pSym->s_type = S_USER;
        pSym->s_area = dot.s_area;
        pSym->s_addr = laddr;
        pSym->s_flag |= S_GBL;
}
#endif


/*)Function	void	DefineNoICE_Line(void)
 *
 *	The function DefineNoICE_Line() is called to create
 *	a symbol of the form FILE.nnn where FILE is the
 *	Base File Name, the file name without a path or
 *	an extension, and nnn is the line number.
 *
 *	local variables:
 *              struct dbuf_s   dbuf    a temporary to build the symbol
 *	        struct sym *	pSym	pointer to the created symbol structure
 *
 *	global variables:
 *              asmf *  asmc            pointer to current assembler file structure
 *		int	srcline		array of source file line numbers
 *		a_uint	laddr		current assembler address
 *		area	dot.s_area	pointer to the current area
 *
 *	functions called:
 *		char *	BaseFileName()	asdbg.c
 *		sym *	lookup()	assym.c
 *		int	sprintf()	c_library
 *
 *	side effects:
 *		A new symbol of the form FILE.nnn is created.
 */

#if NOICE
void
DefineNoICE_Line(void)
{
        struct dbuf_s dbuf;
        struct sym *pSym;

	/*
	 * Symbol is FILE.nnn
	 */
        dbuf_init (&dbuf, NCPS);
        dbuf_printf (&dbuf, "%s.%u", BaseFileName (asmc, 0), srcline);

        pSym = lookup (dbuf_c_str (&dbuf));
        dbuf_destroy (&dbuf);

        pSym->s_type = S_USER;
        pSym->s_area = dot.s_area;
        pSym->s_addr = laddr;
        pSym->s_flag |= S_GBL;
}
#endif


/*)Function	char *	BaseFileName(currFile, spacesToUnderscores)
 *
 *	The function BaseFileName() is called to extract
 *	the file name from a string containing a path,
 *      filename, and extension. If spacesToUnderscores != 0
 *      then spaces are converted to underscores
 *
 *		currFile		is a pointer to the
 *					current assembler object
 *              spacesToUnderscores
 *
 *	local variables:
 *		char	baseName[]	a place to put the file name
 *	        int	prevFile	previous assembler object
 *		char *	p1		temporary string pointer
 *		char *	p2		temporary string pointer
 *
 *	global variables:
 *		FILE *	ofp		output file handle
 *
 *	functions called:
 *		int	fprintf()	c_library
 *		char *	strcpy()	c_library
 *		char *	strrchr()	c_library
 *              char *  isspace()       c_library
 *
 *	side effects:
 *		A FILE command of the form ';!FILE string'
 *		is written to the output file.
 */

#if (NOICE || SDCDB)
static	struct	asmf *prevFile = NULL;
static	char	baseName[FILSPC];

char*
BaseFileName(struct asmf * currFile, int spacesToUnderscores)
{
        char *p1, *p2;

	if (currFile != prevFile) {
        	prevFile = currFile;

		strcpy(baseName, afn);
                p1 = baseName;

                /*
	         * Dump a FILE command with full path and extension
		 */
                if (ofp)
                  fprintf(ofp, ";!FILE %s\n", p1);

		/*
		 * The name starts after the last
		 * '/' (Unices) or
		 * ':' or '\' (DOS)
		 *
		 * and ends at the last
		 * separator 'FSEPX'
		 */
		if ((p2 = strrchr(p1,  '\\')) != NULL)  p1 = ++p2;
		if ((p2 = strrchr(p1,   '/')) != NULL)  p1 = ++p2;
		if ((p2 = strrchr(p1,   ':')) != NULL)  p1 = ++p2;
		if ((p2 = strrchr(p1, FSEPX)) != NULL) *p2 = 0;
                memmove(baseName, p1, strlen(p1)+1); /* Do not use strcpy(), since baseName and p1 may overlap */

                if (spacesToUnderscores) {
                        /* Convert spaces to underscores */
                        for (p1 = baseName; *p1; ++p1)
                                if (isspace (*p1))
                                        *p1 = '_';
                }
	}
	return(baseName);
}
#endif


